/*
    This is a set of libraries to assist in OpenGl and Other Applications
    Copyright (C) 2008  The Modular Engine Team

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "TestModule.h"

namespace ModularEngine
{

	void TestModule::NETPROCSERVER::processMessage(int nMessage, char *pBuffer, int nSize, int nUser)
	{
		int size = clients.size()-1;
		if( !(nUser > ((int)clients.size()-1)) && nMessage != GM_MSG_END)
		{
			if( clients[nUser].mbInLargeMessage )
			{ 
				clients[nUser].mnLargeMessageType = nMessage;
				clients[nUser].mnLargeMessageSize += nSize;
				realloc( clients[nUser].mcLargeMessageBuffer, clients[nUser].mnLargeMessageSize );
				memcpy( clients[nUser].mcLargeMessageBuffer + clients[nUser].mnLargeMessageSize - nSize, pBuffer, nSize );				
				return;
			} 

		}

		switch( nMessage )
		{
		case GM_CHAT:
			{
				// need to redirect to all users
				
				ServerModule::getSingleton().sendMessage( nMessage, SM_ALL, 0, pBuffer, nSize );
			} break;
		case GM_VERSIONCHECK:
			{
				console( "Error: User Requesting Version....  What an idiot!" );
			} break;
		case GM_FILE:
			{
				console( "Error: File Sending Not Yet Implemented" );
			} break;
		case GM_FILECHECK:
			{
				console( "Error: File Checks Not Yet Implemented" );
			} break;
		case GM_NEWUSER:
			{
				ClientHelper nHelper;
				clients.push_back( nHelper );
				
				console( "User claims to be new" );
				// Send authentication requests and stuff here
			} break;
		case GM_LOSTUSER:
			{
				console( "User disconnected" );
			} break;
		case GM_WBPOINT:
			{
				ServerModule::getSingleton().sendMessage( nMessage, SM_ALL, 0, pBuffer, nSize );
			} break;
		case GM_MSG_BEGIN:
			{
				clients[nUser].mcLargeMessageBuffer = new char[PACKET_BUFFER_LENGTH];
				clients[nUser].mbInLargeMessage = true;
				clients[nUser].mnLargeMessageSize = 0;
			} break;
		case GM_MSG_END:
			{
				clients[nUser].mbInLargeMessage = false;
				//cout << clients[nUser].mbLargeMessageBuffer << endl;
				processMessage( clients[nUser].mnLargeMessageType, clients[nUser].mcLargeMessageBuffer, clients[nUser].mnLargeMessageSize, nUser );
				delete [] clients[nUser].mcLargeMessageBuffer;
				clients[nUser].mcLargeMessageBuffer = 0;
				clients[nUser].mnLargeMessageType = 0;
			} break;
		case GM_WBSTART:
		case GM_WBEND:
			{
				ServerModule::getSingleton().sendMessage( nMessage, SM_ALL, 0 );

			} break;
		default:
			{
				console( "User sent unknown command" );
			} break;
		}

		
		return ;

	}

	void TestModule::NETPROCSERVER::operator ()(ModularEngine::NetworkMessage msg)
	{
		processMessage( msg.nMsgType, msg.cBuffer, msg.nSize, msg.nUser );
	}

	void TestModule::NETPROCCLIENT::processMessage( int nMessage, char *pBuffer, int nSize, int nUser )
	{	

		if( nMessage != GM_MSG_END && mbInLargeMessage )
		{
			mnLargeMessageType = nMessage;
			mnLargeMessageSize += nSize;
			realloc( mcLargeMessageBuffer, mnLargeMessageSize );
			memcpy( mcLargeMessageBuffer + mnLargeMessageSize - nSize, pBuffer, nSize );
			return;
		}

		switch( nMessage )
		{
		case GM_CHAT:
			{
				console( pBuffer );
			} break;
		case GM_MSG_BEGIN:
			{
				mcLargeMessageBuffer = new char[PACKET_BUFFER_LENGTH];
				mbInLargeMessage = true;
				mnLargeMessageSize = 0;
			} break;
		case GM_MSG_END:
			{
				mbInLargeMessage = false;
				processMessage( mnLargeMessageType, mcLargeMessageBuffer, mnLargeMessageSize, nUser );
				delete [] mcLargeMessageBuffer;
				mcLargeMessageBuffer = 0;
				mnLargeMessageType = 0;
			} break;
		case GM_WBPOINT:
			{
				Vector3d *vec = (Vector3d *)pBuffer;
				TestModule::getSingleton().WB.mvPoints.push_back( *vec );
			} break;
		case GM_WBSTART:
			{

			} break;
		case GM_WBEND:
			{
				TestModule::getSingleton().WB.wbSplines.push_back( TestModule::getSingleton().WB.mvPoints );
				TestModule::getSingleton().WB.mvPoints.clear();
			} break;

		}


		return ;

	}
		
	void TestModule::NETPROCCLIENT::operator ()(ModularEngine::NetworkMessage msg)
	{
		processMessage( msg.nMsgType, msg.cBuffer, msg.nSize, msg.nUser );
	}

}